home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / dvmulti.arc / SLAVE.C < prev    next >
C/C++ Source or Header  |  1989-10-25  |  8KB  |  329 lines

  1. /* Slave program for DESQview tests
  2.  
  3.     1989    MIPS Magazine / Mark Mallett
  4.  
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <fcntl.h>
  9. #include <dvapi.h>
  10. #include "dvmulti.h"
  11.  
  12. /* Resolution of the timer (ticks per second) */
  13. #define    TIMERES        100
  14.  
  15. /* Timer ticks per day */
  16. #define    DAYTIMER    ((long)(60L*60*24*TIMERES))
  17.  
  18. /* External routines */
  19.  
  20. extern    char    *malloc();
  21.  
  22.  
  23. /* Forward routines */
  24.  
  25.     ULONG    timenow();
  26.  
  27.  
  28. /* Local Variables */
  29.  
  30. static    char    **Buflist;        /* Ptrs to buffers */
  31. static    int    BufN;            /* Current I/O buffer */
  32. static    char    Filename[100];
  33. static    char    IotestF;        /* If doing I/O test */
  34. static    int    Iofd;            /* FD for test file */
  35. static    ULONG    Kbd_main;        /* Main keyboard object handle */
  36. static    ULONG    Mal_main;        /* Main mailbox */
  37. static    ULONG    Mal_super;        /* Supervisor's mailbox */
  38. static    ULONG    Tim_main;        /* for timer */
  39. static    ULONG    Tim_tod;        /* Time-of-day timer */
  40. static    ULONG    Time_all;        /* Ticks spent in program */
  41. static    ULONG    Time_cpu;        /* Ticks spent in CPU section */
  42. static    ULONG    Time_read;        /* Ticks spent in I/O read */
  43. static    ULONG    Time_write;        /* Ticks spent in I/O write */
  44. static    ULONG    Tsk_super;        /* Supervisor's task handle */
  45. static    ULONG    Win_main;        /* Main window */
  46.  
  47. static    CNMSG    Cnfmsg;            /* The configuration message */
  48. static    RSMSG    Rptmsg;            /* The report message */
  49.  
  50. main()
  51. {
  52.     int        version;    /* Version of current dv */
  53.  
  54.     version = api_init();
  55.      if ( version < DVVER ) {
  56.     fprintf( stderr, "DESQview version %d.%02d or later required.\n",
  57.           DVVER/256, DVVER%256 );
  58.     }
  59.     else {
  60.     api_level( DVVER );
  61.     slave();
  62.     }
  63.  
  64.     if ( version != 0 )
  65.     api_exit();
  66. }
  67.  
  68.  
  69.  
  70. /* The functional main program of the supervisor program.  Called after
  71.    DESQview environment is established. */
  72.  
  73. slave()
  74. {
  75.     int        msgcode;    /* Message code... */
  76.     int        msgL;        /* Mail message length */
  77.     char        *msgP;        /* Mail message ptr */
  78.     long        loopC;        /* Execution loop counter */
  79.  
  80.     /* Get handles to main window, keyboard, mailbox, and timers. */
  81.     Win_main = win_me();
  82.     Kbd_main = key_me();
  83.     Mal_main = mal_me();
  84.     Tim_main = tim_new();
  85.     Tim_tod = tim_new();
  86.  
  87.     /* Put up startup message in our window */
  88.     win_erase( Win_main );
  89.     win_printf( Win_main, "Need CONFIG\n" );
  90.  
  91.     /* Wait for configuration message from supervisor */
  92.     for( ; ; ) {
  93.     msgcode = mal_read( Mal_main, &msgP, &msgL );
  94.     if ( msgcode == MSG_CONFIG )
  95.         break;
  96.     }
  97.  
  98.     /* Perform configuration */
  99.     win_erase( Win_main );
  100.     win_printf( Win_main, "Init...\n" );
  101.     if ( !configure( msgP, msgL ) )
  102.     return;
  103.  
  104.     /* Ready to go... send ready message. */
  105.     mal_addto( Mal_super, NULL, 0, MSG_READY );
  106.    
  107.     win_erase( Win_main );
  108.     win_printf( Win_main, "Need GO\n" );
  109.  
  110.     /* Wait for GO message from supervisor */
  111.     for( ; ; ) {
  112.     msgcode = mal_read( Mal_main, &msgP, &msgL );
  113.     if ( msgcode == MSG_GO )
  114.         break;
  115.     }
  116.  
  117.     /* Run now */
  118.     win_erase( Win_main );
  119.     win_printf( Win_main, "Running...\n" );
  120.  
  121.     /* Get start time */
  122.     Time_all = timenow();
  123.     
  124.     for( loopC = 0; ; ++loopC ) {
  125.     /* Check for stop request */
  126.     if ( mal_sizeof( Mal_main ) != 0 ) {
  127.         do
  128.         msgcode = mal_read( Mal_main, &msgP, &msgL );
  129.         while( ( msgcode != MSG_STOP ) &&
  130.            ( mal_sizeof( Mal_main ) != 0 ) );
  131.         if ( msgcode == MSG_STOP )
  132.         break;
  133.     }
  134.  
  135.     /* Perform I/O function */
  136.     iotest();
  137.  
  138.     /* Perform cpu test */
  139.     cputest();
  140.  
  141.     /* Sleep for the designated interval */
  142.     if ( Cnfmsg.cm_sleep != 0 ) {
  143.         tim_addto( Tim_main, Cnfmsg.cm_sleep );
  144.         tim_read( Tim_main );
  145.     }
  146.     }
  147.  
  148.     /* All done */
  149.     Time_all = timenow() - Time_all;
  150.  
  151.     /* Report now */
  152.     win_erase( Win_main );
  153.     win_printf( Win_main, "Reporting...\n" );
  154.  
  155.     Rptmsg.rm_loopC = (long)loopC;
  156.     report();
  157. }
  158.  
  159.  
  160. /* Perform the I/O test */
  161. iotest()
  162. {
  163.     extern    int    read();
  164.     extern    int    write();
  165.  
  166.     if ( !IotestF )
  167.     return;
  168.  
  169.     if ( Cnfmsg.cm_readF )
  170.     io_run( read, &Time_read );
  171.     if ( Cnfmsg.cm_writeF )
  172.     io_run( write, &Time_write );
  173. }
  174.  
  175.  
  176. io_run( iortc, timeP )
  177.     int        (*iortc)();    /* I/O routine to call */
  178.     ULONG        *timeP;        /* Ptr to timer counter */
  179. {
  180.     int        block;
  181.     long        loopC;        /* I/O loop counter */
  182.     long        filepos;    /* File position to use */
  183.     ULONG        timer;        /* Timer counter */
  184.     char        *bufP;
  185.  
  186.     /* Get start time */
  187.     timer = timenow();
  188.  
  189.     /* If sequential I/O, start at the beginning */
  190.     if ( Cnfmsg.cm_seqF )
  191.     lseek( Iofd, filepos = 0L, 0 );
  192.  
  193.     /* Perform the specified number of loops */
  194.     for( loopC = 0; loopC < Cnfmsg.cm_ioC; ++loopC ) {
  195.     /* Select next buffer */
  196.     if ( ++BufN == Cnfmsg.cm_iobufC )
  197.         BufN = 0;
  198.     bufP = Buflist[BufN];
  199.  
  200.     /* Select appropriate file position */
  201.     if ( Cnfmsg.cm_seqF ) {
  202.         if ( filepos + Cnfmsg.cm_xsize >= Cnfmsg.cm_fsize )
  203.         lseek( Iofd, filepos = 0L, 0 );
  204.         filepos += Cnfmsg.cm_xsize;    /* Next position */
  205.     }
  206.     else {
  207.         /* Choose a random file position */
  208.         block = rand() % (int)( Cnfmsg.cm_fsize/Cnfmsg.cm_xsize -1 );
  209.         filepos = block * Cnfmsg.cm_xsize;
  210.         lseek( Iofd, filepos, 0 );
  211.     }
  212.  
  213.     /* Perform the disk transfer */
  214.     (*iortc)( Iofd, bufP, Cnfmsg.cm_xsize );
  215.     }
  216.  
  217.     /* Accumulate the elapsed time */
  218.     *timeP = *timeP + (timenow() - timer);
  219. }
  220.  
  221.  
  222.  
  223.  
  224. /* Perform the CPU test */
  225. cputest()
  226. {
  227.     int        i, j, k;
  228.     ULONG        timer;        /* Time in this routine */
  229.  
  230.     if ( Cnfmsg.cm_cpuC == 0 )
  231.     return;
  232.  
  233.     timer = timenow();            /* Start the timer */
  234.  
  235.     for( i = 0; i < Cnfmsg.cm_cpuC; ++i )
  236.     for( j = 0; j < 1000; ++j )
  237.         k = rand();
  238.  
  239.     Time_cpu = Time_cpu + ( timenow() - timer );
  240. }
  241.  
  242.  
  243. /* Process configuration message, do initialization... */
  244.  
  245. configure( cmsgP, cmsgL )
  246.     CNMSG        *cmsgP;        /* Ptr to configure msg */
  247.     int        cmsgL;        /* Length of the message */
  248. {
  249.     int        i;
  250.     long        size;
  251.     char        kbuf[1024];
  252.  
  253.     /* Get sender of config message */
  254.     Tsk_super = mal_addr( Mal_main );
  255.     Mal_super = mal_of( Tsk_super );
  256.  
  257.     /* Make sure configuration message is (at least) the right size */
  258.     if ( cmsgL < sizeof(CNMSG) )
  259.     return (FALSE);
  260.  
  261.     /* Stash configuration parameters for later use */
  262.     memcpy( &Cnfmsg, cmsgP, sizeof(CNMSG) );
  263.  
  264.     /* Setup for I/O if we need to do any */
  265.     if ( ( Cnfmsg.cm_readF || Cnfmsg.cm_writeF ) &&
  266.          ( Cnfmsg.cm_ioC != 0 )    ) {
  267.  
  268.     IotestF = TRUE;
  269.  
  270.     /* Allocate the buffers */
  271.     Buflist = (char **)malloc( Cnfmsg.cm_iobufC * sizeof(char *) );
  272.     for( i = 0; i < Cnfmsg.cm_iobufC; ++i )
  273.         Buflist[i] = (char *)malloc( Cnfmsg.cm_xsize );
  274.     BufN = 0;
  275.  
  276.     /* Make the data file */
  277.     sprintf( &Filename[0], "Slave%03d.dat", Cnfmsg.cm_taskN );
  278.     Iofd = open( &Filename[0], O_RDWR|O_CREAT|O_BINARY, 0666 );
  279.     if ( Iofd < 0 )
  280.         return( FALSE );
  281.  
  282.     /* Populate the file */
  283.     for( size = 0; size < Cnfmsg.cm_fsize; size += 1024 )
  284.         write( Iofd, &kbuf[0], 1024 );
  285.     }
  286.     else
  287.     IotestF = FALSE;
  288.  
  289.     /* Start the time-of-day timer running */
  290.     tim_write( Tim_tod, (long)(DAYTIMER -1) );
  291.  
  292.     return( TRUE );
  293. }
  294.  
  295.  
  296.  
  297. /* Send a report back to the supervisor task */
  298. report()
  299. {
  300.     float        x;
  301.  
  302. win_erase( Win_main );
  303. win_printf( Win_main, "loops=%d\n", (int)Rptmsg.rm_loopC );
  304.  
  305.     Rptmsg.rm_tick = TIMERES;
  306.     Rptmsg.rm_alltime = Time_all;
  307.     Rptmsg.rm_readtime = Time_read;
  308.     Rptmsg.rm_writetime = Time_write;
  309.     Rptmsg.rm_cputime = Time_cpu;
  310.  
  311. /*    Rptmsg.rm_alltime = ((float)Time_all)/(float)TIMERES;
  312.     Rptmsg.rm_readtime = ((float)Time_read)/(float)TIMERES;
  313.     Rptmsg.rm_writetime = ((float)Time_write)/(float)TIMERES;
  314.     Rptmsg.rm_cputime = ((float)Time_cpu)/(float)TIMERES;
  315. */
  316.  
  317.     mal_addto( Mal_super, &Rptmsg, sizeof(RSMSG), MSG_REPORT );
  318. }
  319.  
  320.  
  321.  
  322. /* Get time now, from the time-of-day timer */
  323.  
  324. ULONG
  325. timenow()
  326. {
  327.     return( DAYTIMER - tim_len( Tim_tod ) );
  328. }
  329.